#include <iostream>
#include <string>

using namespace std;

// ok
string version1(const string &s1, const string &s2);

// ok
const string &version2(string &s1, const string &s2);

// fail
const string &version3(string &string1, const string &string2);
int main()
{
    string input;
    string copy;
    string result;

    cout << "Enter string" << endl;
    getline(cin, input);
    copy = input;
    cout << "Your string as entered " << input << endl;

    cout << "Your origin input is :" << input << endl;
    result = version1(input, "***");

    // 这种调用是可行的: (input, "***")
    // 调用函数时: 因为是 形参是 'const' string &, 虽然"***"是一个char * 类型,实参和形参引用类型不匹配,
    // 但是char *类型的字符串可以通过string的一种方法转换成string引用对象,程序将会创建一个正确类型的临时变量,
    // 使用转换后的实参值进行初始化,然后传递一个指向这个临时变量的引用

    //
    cout << "your enhanced string is :" << result << endl;

    cout << "Your origin input is :" << input << endl;
    result = version2(input, "###");
    cout << "your enhanced string is :" << result << endl;

    cout << "Your origin input is :" << input << endl;
    result = version3(input, "@@@");
    // Warning: 程序到此处应该崩溃,因为引用了已经消失的地址,程序试图引用已经释放的内存
    // (0xC0000005)
    cout << "your enhanced string is :" << result << endl;

    return 0;
}

/*
Enter string
quzihang

Your string as entered quzihang
Your origin input is :quzihang
your enhanced string is :***quzihang***
Your origin input is :quzihang
your enhanced string is :###quzihang###
Your origin input is :###quzihang###
*/

string version1(const string &s1, const string &s2)
{
    string temp;
    temp = s2 + s1 + s2;
    return temp;
}

const string &version2(string &s1, const string &s2)
{
    s1 = s2 + s1 + s2;
    // 直接修改的引用,所以会直接更改传入的s1的值
    return s1;
}

const string &version3(string &string1, const string &string2)
{
    string temp; // 创建了一个临时变量,但是一旦离开这个函数,这个临时变量将会消失,
    // 所以返回的时候不要使用像这个函数中的写法,尽量使用值传递的方式,就像version1()函数

    temp = string2 + string1 + string2; // 修改了这个变量
    return temp;                        // 返回了这个变量的引用
    // 25ReferenceInUsingObject.cpp:82:12: 
    // 警告：reference to local variable ‘temp’ returned [-Wreturn-local-addr]
}
